<!--
    by: yuanbiao 2021年06月15日
    name: x-pptx-viewer
    notes:
-->
<template>
  <div :class="[`${prefixCls}`]">
    <!-- <style v-for="(v,i) in stylesArr" :key="i">{{v}}</style> -->
    <section v-for="(v,i) in slides" :key="i"
      :class="[`${prefixCls}__slide`]"
      :style="slideStyle"
    ></section>
  </div>
</template>

<script>
import Toast from '@/components/toast/index.js'
// import {isArrayBuffer, typeOf} from '@/script/utils.js'
// const axios = require('axios')
// const iconv = require('iconv-lite')
const d3 = require('d3')
const nv = require('nvd3')
const prefixCls = 'x-pptx-viewer'
export default {
  name: 'x-pptx-viewer',
  props: {
    data: {
      type: Blob,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      prefixCls: prefixCls,
      loadProgress: 0,
      stylesArr: [],
      slicesArr: [],
      pptxThumb: '',
      execTime: 0,
      filedata: ''
    }
  },
  watch: {
    data: {
      handler (n) {
        this.processData(n)
      },
      deep: true,
      immediate: true
    }
  },
  computed: {
    slides () {
      let result = []
      let _slides = (this.data || {}).slides || []
      _slides.forEach(v => {
        if (v && v.pageElements) {
          let pageElements = []
          v.pageElements.forEach(ele => {
            let position = ele.position || {}
            let size = ele.size || {}
            // let shape = ele.shape || {}
            // let text = shape.text || {}
            pageElements.push({
              style: {
                position: 'absolute',
                left: this.mergeValueUnit(position.x),
                top: this.mergeValueUnit(position.y),
                width: this.mergeValueUnit(size.width),
                height: this.mergeValueUnit(size.height),
              }
            })
          })
        }
      })
      return result
    },
    slideStyle () {
      let {width, height} = this.data.pageSize || {}
      return {
        width: this.mergeValueUnit(width),
        height: this.mergeValueUnit(height)
      }
    }
  },
  methods: {
    processData (data) {
      if (!window.Worker) {
        Toast('您的浏览器不支持 Web Worker')
        return
      }
      let worker = new Worker('./pptx-worker.js')
      worker.addEventListener('message', (e) => {
        let msg = e.data || {}
        switch(msg.type) {
          case 'progress-update':
            this.loadProgress = msg.data.toFixed(2)
            break
          case 'processMsgQueue':
            this.processMsgQueue(msg.data)
            break
          case 'pptx-thumb':
            this.pptxThumb = `data:image/jpeg;base64,${msg.data}`
            break
          case 'slide':
            this.slicesArr.push(msg.data)
            break
          case 'slideSize':
              localStorage.setItem('slideWidth', msg.data.width)
              localStorage.setItem('slideHeight', msg.data.height)
            break
          case 'globalCSS':
            this.stylesArr.push(msg.data)
            break
          case 'ExecutionTime':
            this.execTime = msg.data // 执行时间(ms)
            this.$emit('loaded', msg.data)
            worker.postMessage({ type: 'getMsgQueue' })
            break
          case 'WARN':
            console.warn('Worker: ', msg.data)
            break
          case 'ERROR':
            console.error('Worker: ', msg.data)
            Toast(msg.data)
            break
          case 'DEBUG':
            console.debug('Worker: ', msg.data)
            break
          case 'INFO':
          default:
            console.info('Worker: ', msg.data)
        }

      }, false)
      worker.postMessage({ type: 'processPPTX', data })
    },
    processQueueMsg (queue) {
      for (let i=0; i < queue.length; i++) {
        this.processSingleMsg(queue[i].data)
      }
    },
    processSingleMsg (msg) {
      let {chartID, chartType, chartData} = msg || {}
      let _data =  []
      let chart = null
      switch (chartType) {
        case "lineChart":
          _data = chartData;
          chart = nv.models.lineChart()
                .useInteractiveGuideline(true);
          chart.xAxis.tickFormat(function(d) { return chartData[0].xlabels[d] || d; });
          break;
        case "barChart":
          _data = chartData;
          chart = nv.models.multiBarChart();
          chart.xAxis.tickFormat(function(d) { return chartData[0].xlabels[d] || d; });
          break;
        case "pieChart":
        case "pie3DChart":
          _data = chartData[0].values;
          chart = nv.models.pieChart();
          break;
        case "areaChart":
          _data = chartData;
          chart = nv.models.stackedAreaChart()
                .clipEdge(true)
                .useInteractiveGuideline(true);
          chart.xAxis.tickFormat(function(d) { return chartData[0].xlabels[d] || d; });
          break;
        case "scatterChart":

          for (var i=0; i<chartData.length; i++) {
            var arr = [];
            for (var j=0; j<chartData[i].length; j++) {
              arr.push({x: j, y: chartData[i][j]});
            }
            _data.push({key: 'data' + (i + 1), values: arr});
          }

          //data = chartData;
          chart = nv.models.scatterChart()
                .showDistX(true)
                .showDistY(true)
                .color(d3.scale.category10().range());
          chart.xAxis.axisLabel('X').tickFormat(d3.format('.02f'));
          chart.yAxis.axisLabel('Y').tickFormat(d3.format('.02f'));
          break;
        default:
      }

      if (chart !== null) {

        d3.select("#" + chartID)
          .append("svg")
          .datum(_data)
          .transition().duration(500)
          .call(chart);

        nv.utils.windowResize(chart.update);

      }

    },
    mergeValueUnit (obj = {}) {
      let value = (obj || {}).value || 0
      let unit = (obj || {}).unit || ''
      return `${value}${unit}`
    }
  }
}
</script>

<style>
.x-pptx-viewer__slide {
  position: relative;
}
</style>
